package ugroupcontroller

import (
	"context"
	"encoding/json"
	"vpn-management-server/logger"
	"vpn-management-server/network"
	"vpn-management-server/security/code"
	"vpn-management-server/src/dao/ugroupdao"
	"vpn-management-server/src/dao/userdao"
	"vpn-management-server/src/model/adminmodel"
	"vpn-management-server/src/model/ugroupmodel"
	"vpn-management-server/src/model/usermodel"
	"vpn-management-server/src/service/adminservice"
	"vpn-management-server/src/service/ugroupservice"
)

// GetUGroupUsersByPage 分页获取用户组中的用户信息
func GetUGroupUsersByPage(ctx context.Context, request *network.NetRequest, response *network.NetResponse) {
	if usersByPage, ok := request.GetModel().(*ugroupmodel.PageWithID); ok {
		var Users = struct {
			Users []*usermodel.User
			Count int
		}{}
		users := userdao.GetUGroupUsersByPage(usersByPage.UGroupID, usersByPage.PageNo, usersByPage.PageSize)
		if users == nil {
			users = []*usermodel.User{}
			logger.Logger.Warn("users is empty")
		}
		count := userdao.GetUserCountByUGroupID(usersByPage.UGroupID)
		if count == -1 {
			logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "get users count fail")
			response.Code = code.INTERNAL_SERVER_ERROR
			response.ErrorMsg = "get users count fail"
			return
		}
		Users.Users = users
		Users.Count = count
		data, _ := json.Marshal(Users)
		response.Code = code.SUCCESS
		response.Data = data
		return
	} else {
		// TODO 转换失败 回送信息
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "Transform interface to userNameInfo fail")
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "transform interface to UsersByPage fail"
		return
	}
}

// GetUGroupUserNameInfos 获得用户组内所有用户名
func GetUGroupUserNameInfos(ctx context.Context, request *network.NetRequest, response *network.NetResponse) {
	if UGroupNameInfo, ok := request.GetModel().(*ugroupmodel.UGroupNameInfo); ok {
		userNameInfos := userdao.GetAllUserInfosByUGroupID(UGroupNameInfo.ID)
		if userNameInfos == nil {
			userNameInfos = []*usermodel.UserNameInfo{}
			logger.Logger.Warn("users is empty")
		}
		data, _ := json.Marshal(userNameInfos)
		response.Code = code.SUCCESS
		response.Data = data
		return

	} else {
		// TODO 转换失败 回送信息
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "Transform interface to userNameInfo fail")
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "transform interface to userNameInfo fail"
		return
	}
}

// AddUserGroup 创建用户组函数
func AddUserGroup(ctx context.Context, request *network.NetRequest, response *network.NetResponse) {
	if UGroup, ok := request.GetModel().(*ugroupmodel.UGroup); ok {
		if !ugroupdao.HasUGroupByName(UGroup.Name) {
			err := ugroupdao.AddUGroup(UGroup)
			if err != nil {
				logger.Logger.ErrorfWithConn(ctx.Value("conn_id").(string), "add user group %s fail\n", UGroup.Name)
				response.Code = code.INTERNAL_SERVER_ERROR
				response.ErrorMsg = "add user group fail"
				return
			}
			logger.Logger.Infof("add user group %s success\n", UGroup.Name)
			UGroup = ugroupdao.GetUGroupByName(UGroup.Name)
			response.Code = 200
			data, _ := json.Marshal(UGroup)
			response.Data = data
			return
		} else {
			logger.Logger.ErrorfWithConn(ctx.Value("conn_id").(string), "user group %s exist\n", UGroup.Name)
			response.Code = code.FORBIDDEN
			response.ErrorMsg = "user group exist"
			return
		}
	} else {
		// TODO 转换失败 回送信息
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "Transform interface to UGroup fail")
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "transform interface to UGroup fail"
		return
	}
}

// DeleteUserGroup 删除用户组函数
func DeleteUserGroup(ctx context.Context, request *network.NetRequest, response *network.NetResponse) {
	if UGroupNameInfo, ok := request.GetModel().(*ugroupmodel.UGroupNameInfo); ok {
		if ugroupdao.HasUGroupByName(UGroupNameInfo.Name) {
			err := ugroupservice.DeleteUGroupService(UGroupNameInfo.ID)
			if err != nil {
				logger.Logger.ErrorfWithConn(ctx.Value("conn_id").(string), err.Error())
				response.Code = code.INTERNAL_SERVER_ERROR
				response.ErrorMsg = err.Error()
				return
			}
			logger.Logger.Infof("delete user group %s success\n", UGroupNameInfo.Name)
			response.Code = 200
			return
		} else {
			logger.Logger.ErrorfWithConn(ctx.Value("conn_id").(string), "user group %s exist\n", UGroupNameInfo.Name)
			response.Code = code.FORBIDDEN
			response.ErrorMsg = "user group not exist"
			return
		}
	} else {
		// TODO 转换失败 回送信息
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "Transform interface to UGroup fail")
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "transform interface to UGroup fail"
		return
	}
}

// GetUserGroupsByPage 超级管理员和系统管理员限定
func GetUserGroupsByPage(ctx context.Context, request *network.NetRequest, response *network.NetResponse) {
	if page, ok := request.GetModel().(*ugroupmodel.Page); ok {
		var ugroups = struct {
			UGroups []*ugroupmodel.UGroup
			Count   int
		}{}
		ugroups.UGroups = ugroupdao.GetUGroupByPage(page.PageNo, page.PageSize)
		if ugroups.UGroups == nil {
			ugroups.UGroups = []*ugroupmodel.UGroup{}
			logger.Logger.Warn("user group is empty")
		}
		ugroups.Count = ugroupdao.GetUGroupCount()
		data, _ := json.Marshal(ugroups)
		response.Code = 200
		response.Data = data
		logger.Logger.Info("get page user group info success")
		return
	} else {
		// TODO 转换失败 回送信息
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "Transform interface to UserGroupsByPage fail")
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "transform interface to UserGroupsByPage fail"
		return
	}
}

// GetAllUserGroupNameInfos 获得所有用户组的名字
func GetAllUserGroupNameInfos(ctx context.Context, request *network.NetRequest, response *network.NetResponse) {
	UGroupNameInfos := ugroupdao.GetAllUGroupNameInfos()
	if UGroupNameInfos == nil {
		UGroupNameInfos = []*ugroupmodel.UGroupNameInfo{}
		logger.Logger.Warn("user group is empty")
	}
	data, _ := json.Marshal(UGroupNameInfos)
	response.Code = 200
	response.Data = data
	logger.Logger.Info("get user group name info success")
	return
}

// GetUserGroupByName 搜索框中用到
func GetUserGroupByName(ctx context.Context, request *network.NetRequest, response *network.NetResponse) {
	if UGroupNameInfo, ok := request.GetModel().(*ugroupmodel.UGroupNameInfo); ok {
		if ugroupdao.HasUGroupByName(UGroupNameInfo.Name) {
			UGroup := ugroupdao.GetUGroupByName(UGroupNameInfo.Name)
			if UGroup == nil {
				logger.Logger.ErrorfWithConn(ctx.Value("conn_id").(string), "get user group %s fail\n", UGroupNameInfo.Name)
				response.Code = code.INTERNAL_SERVER_ERROR
				response.ErrorMsg = "get user group fail"
				return
			}
			data, _ := json.Marshal(UGroup)
			response.Code = 200
			response.Data = data
			logger.Logger.Infof("get user group %s success\n", UGroupNameInfo.Name)
			return
		} else {
			logger.Logger.ErrorfWithConn(ctx.Value("conn_id").(string), "user group %s exist\n", UGroupNameInfo.Name)
			response.Code = code.FORBIDDEN
			response.ErrorMsg = "user group not exist"
			return
		}
	} else {
		// TODO 转换失败 回送信息
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "Transform interface to UGroup fail")
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "transform interface to UGroupNameInfo fail"
		return
	}
}

func GetUGroupByCurrAdmin(ctx context.Context, request *network.NetRequest, response *network.NetResponse) {
	admin := adminservice.GetCurrAdminService(ctx, request, response)
	if admin == nil {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "admin info is expired")
		response.Code = code.FORBIDDEN
		response.ErrorMsg = "admin info is expired"
		return
	}
	if admin.Rank != adminmodel.UserGroupAdmin {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "have no authority")
		response.Code = code.UNAUTHORIZED
		response.ErrorMsg = "have no authority"
		return
	}
	ugroup := ugroupdao.GetUGroupByAdminID(admin.ID)
	if ugroup == nil {
		logger.Logger.Warn("admin have no user group")
		ugroup = &ugroupmodel.UGroup{}
	}
	data, _ := json.Marshal(ugroup)
	response.Code = code.SUCCESS
	response.Data = data
	logger.Logger.Info("get user group success")
	return
}

func GetUGroupNameInfosWithoutAdmin(ctx context.Context, request *network.NetRequest, response *network.NetResponse) {
	if rank := adminservice.GetAdminRankService(ctx, request, response); rank == adminmodel.SuperAdmin || rank == adminmodel.SystemAdmin {
		UGroupNameInfos := ugroupdao.GetUGroupNameInfosWithoutAdmin()
		data, _ := json.Marshal(UGroupNameInfos)
		response.Code = 200
		response.Data = data
		logger.Logger.Info("get page user group whithout admin info success")
		return
	} else {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "have no authority")
		response.Code = code.UNAUTHORIZED
		response.ErrorMsg = "have no authority"
		return
	}
}
